#include "server_core.hpp"
#include "../common/thread_pool.hpp"
#include <unordered_map>
#include <set>
#include <mutex>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <iostream>

static ThreadPool* pool = nullptr;
static std::unordered_map<int, std::string> nicknames;
static std::set<int> client_fds;
static std::mutex data_mutex;

void init_server_core(ThreadPool* p) {
    pool = p;
}

void register_client(int fd) {
    std::lock_guard<std::mutex> lock(data_mutex);
    nicknames[fd] = "anonymous";
    client_fds.insert(fd);
    std::cout << "[Server] New connection: fd=" << fd << std::endl;
    std::string ask_name = "[Server] Please enter your nickname:\n";
    send(fd, ask_name.c_str(), ask_name.size(), 0);
}

void unregister_client(int fd) {
    std::lock_guard<std::mutex> lock(data_mutex);
    auto it = nicknames.find(fd);
    if (it != nicknames.end()) {
        std::string name = it->second;
        std::string msg = "[Server] " + name + " left the chat.\n";
        for (int client : client_fds) {
            if (client != fd) {
                send(client, msg.c_str(), msg.size(), 0);
            }
        }
        std::cout << msg;
        nicknames.erase(fd);
    }
    client_fds.erase(fd);
    close(fd);
}

void handle_client_message(int fd, const std::string& msg) {
    pool->enqueue([fd, msg]() {
        std::lock_guard<std::mutex> lock(data_mutex);

        if (nicknames[fd] == "anonymous") {
            nicknames[fd] = msg;
            std::string welcome = "[Server] Welcome, " + msg + "!\n";
            send(fd, welcome.c_str(), welcome.size(), 0);

            std::string notice = "[Server] " + msg + " joined the chat.\n";
            for (int client : client_fds) {
                if (client != fd) {
                    send(client, notice.c_str(), notice.size(), 0);
                }
            }
            std::cout << notice;
            return;
        }
       
        if (msg == "/who") {
    std::string list = "[Server] Online users:\n";
    for (const auto& p : nicknames) {
        list += " - " + p.second + "\n";
    }
    send(fd, list.c_str(), list.size(), 0);
    return;
}


    else  if (msg.rfind("/rename ", 0) == 0) {
    std::string newname = msg.substr(8);
    if (newname.empty()) {
        std::string err = "[Server] Usage: /rename <newname>\n";
        send(fd, err.c_str(), err.size(), 0);
        return;
    }

    std::string oldname = nicknames[fd];
    nicknames[fd] = newname;

    std::string ack = "[Server] Your name is now " + newname + ".\n";
    send(fd, ack.c_str(), ack.size(), 0);

    std::string notice = "[Server] " + oldname + " is now known as " + newname + ".\n";
    for (int client : client_fds) {
        if (client != fd) {
            send(client, notice.c_str(), notice.size(), 0);
        }
    }
    std::cout << notice;
    return;
}


if (msg == "/quit") {
    std::string notice = "[Server] You have disconnected.\n";
    send(fd, notice.c_str(), notice.size(), 0);
    unregister_client(fd); // ✅ 自动广播退出 & 清理
    return;
}


        std::string output = "[" + nicknames[fd] + "]: " + msg + "\n";
        for (int client : client_fds) {
            if (client != fd) {
                send(client, output.c_str(), output.size(), 0);
            }
        }
    });
}

